package com.hrg.rds.infra.executor.impl;

import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.RandomUtil;
import com.hrg.rds.biz.waybill.domain.template.cmd.CmdParam;
import com.hrg.rds.infra.executor.CmdExecutor;
import com.hrg.rds.infra.executor.CmdInstanceContext;
import com.hrg.rds.infra.executor.CmdInstanceResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.nio.ByteBuffer;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service("S7WriteCmd")
public class S7WriteCmdExecutor implements CmdExecutor {
	/*@Autowired
	private S7ConnectionHolder s7ConnectionHolder;
	@Autowired
	private S7Properties s7Properties;*/

	@Override
	public CmdInstanceResult execute(List<CmdParam> params, CmdInstanceContext cmdInstanceContext) {
		log.info("S7WriteCmdExecutor execute, cmdId = "+ cmdInstanceContext.getCmdId());

		try {
			/*Map<String, CmdParam> map = params.stream().collect(Collectors.toMap(CmdParam::getKey, Function.identity()));

			S7Util.S7SingleReq s7SingleReq = new S7Util.S7SingleReq();
			s7SingleReq.setS7MemoryArea(S7MemoryArea.get((map.get("s7MemoryArea").getStringEvaluatedValue().toUpperCase())));
			s7SingleReq.setS7DataType(S7DataType.get(map.get("s7DataType").getStringEvaluatedValue().toUpperCase()));
			s7SingleReq.setStartByteAddress(map.get("startByteAddress").getIntegerEvaluatedValue());
			s7SingleReq.setBitOffset(map.get("bitOffset").getIntegerEvaluatedValue());
			s7SingleReq.setDataBlockNumber(map.get("dataBlockNumber").getIntegerEvaluatedValue());
			s7SingleReq.setStringLength(map.get("stringLength").getIntegerEvaluatedValue());
			s7SingleReq.setValue(map.get("value").getObjectEvaluatedValue());// 填充具体的数据类型

			String hexStr = S7Util.readSingle(s7ConnectionHolder.getConnection(s7Properties.getConnId()), s7SingleReq);

			if (checkReadAsExpect(hexStr, map.get("expectValue"))) {
				return CmdInstanceResult.success();
			}*/
			String hexStr = "write1234";

			// 测试代码，休眠1s
			TimeUnit.SECONDS.sleep(1);

			log.info(hexStr);
			int random = RandomUtil.randomInt(0, 10);
			if (random == 9) {
				log.info("hexStr = {}， random = 9, success", hexStr);
				return CmdInstanceResult.success();
			}
			log.info("hexStr = {}， random != 9, retry", hexStr);
			return CmdInstanceResult.retry();
		} catch (Exception e) {
			log.info("S7WriteCmdExecutor execute error", e);
			return CmdInstanceResult.retry(e.getMessage());
		}
	}

	private boolean checkReadAsExpect(String hexStr, CmdParam cmdParam) {
		byte[] byteArray = HexUtil.decodeHex(hexStr);
		Object expectValue = cmdParam.getObjectEvaluatedValue();
		Class<?> targetType = cmdParam.getParamType().getClazz();
		if (targetType == String.class) {
			String value = new String(byteArray);
			log.info("value = {}, expectValue = {}, equals = {}", value, expectValue, value.equals(expectValue));
			return value.equals(expectValue);
		} else if (targetType == Integer.class) {
			ByteBuffer buffer = ByteBuffer.wrap(byteArray);
			Integer value = buffer.getInt();
			log.info("value = {}, expectValue = {}, equals = {}", value, expectValue, value.equals(expectValue));
			return value.equals(expectValue);
		} else if (targetType == Double.class) {
			ByteBuffer buffer = ByteBuffer.wrap(byteArray);
			Double value = buffer.getDouble();
			log.info("value = {}, expectValue = {}, equals = {}", value, expectValue, value.equals(expectValue));
			return value.equals(expectValue);
		} else if (targetType == Boolean.class) {
			ByteBuffer buffer = ByteBuffer.wrap(byteArray);
			int value = buffer.getInt();
			log.info("value = {}, expectValue = {}, equals = {}", value, expectValue, Boolean.TRUE.equals(expectValue) == (value != 0));
			return Boolean.TRUE.equals(expectValue) == (value != 0);
		}
		return false;
	}
}
